/**
 * Copyright  (c) 2009-2013 XLab,  Org. 
 * All  rights  reserved. 
 */
package org.xlab.baseframework.service.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Service;
import org.xlab.baseframework.dao.api.ISystemLogDAO;
import org.xlab.baseframework.domain.ISystemUserDomain;
import org.xlab.baseframework.domain.SystemCode;
import org.xlab.baseframework.domain.SystemLog;
import org.xlab.baseframework.domain.enumerate.EnumLogLevel;
import org.xlab.baseframework.domain.query.SystemLogQueryObject;
import org.xlab.baseframework.domain.view.SystemLogVO;
import org.xlab.baseframework.exception.ObjectNotFoundException;
import org.xlab.baseframework.exception.SystemCodeDuplicateException;
import org.xlab.baseframework.exception.SystemCodeNotFoundException;
import org.xlab.baseframework.exception.SystemLogNotFoundException;
import org.xlab.baseframework.exception.SystemRuntimeException;
import org.xlab.baseframework.service.api.ISystemCodeService;
import org.xlab.baseframework.service.api.ISystemLogService;
import org.xlab.baseframework.system.PlatformDeclare;

/**
 * <p>
 * 系统日志服务接口实现
 * </p>
 * 
 * @author MaKuBEX Email:makubexnet@gmail.com
 * @version 1.0.0 Sep 7, 2010
 * @since 1.0.0
 * 
 */
@Service
public class SystemLogServiceImpl implements ISystemLogService {

	/**
	 * @serialField
	 */
	private static final long serialVersionUID = -4765147125785850440L;
	private static final Logger log = Logger
			.getLogger(SystemLogServiceImpl.class);
	@Autowired(required = true)
	@Qualifier("bpf_systemLogDAO")
	private ISystemLogDAO systemLogDAO;
	@Autowired(required = true)
	@Qualifier("bpf_systemCodeService")
	private ISystemCodeService systemCodeService;
	@Autowired(required = true)
	@Qualifier("bpf_systemLogServiceMessageSource")
	private MessageSource messageSource;

	/**
	 * @see org.xlab.baseframework.service.api.IBaseService#convertToVO(java.io.Serializable)
	 */
	public SystemLogVO convertToVO(SystemLog entity) {
		SystemLogVO vo = new SystemLogVO(entity);
		return vo;
	}

	/**
	 * @see org.xlab.baseframework.service.api.IBaseService#convertToVOList(java.util.Collection)
	 */
	public List<SystemLogVO> convertToVOList(
			Collection<SystemLog> entityCollection) {
		List<SystemLogVO> result = new ArrayList<SystemLogVO>(
				entityCollection.size());
		for (SystemLog sysLog : entityCollection) {
			result.add(this.convertToVO(sysLog));
		}
		return result;
	}

	/**
	 * @see org.xlab.baseframework.service.api.ISystemLogService#createSystemLog(java.lang.String,
	 *      java.lang.String, org.xlab.baseframework.domain.ISystemUserDomain)
	 */
	public void createSystemLog(String title, String content,
			EnumLogLevel logLevel, ISystemUserDomain createdBy) {
		SystemCode logType = null;
		try {
			logType = this.systemCodeService.findByCode(
					PlatformDeclare.CODE_OF_LOGTYPE_EXCEPTION, true);
			Date current = new Date();
			SystemLog sysLog = new SystemLog();
			sysLog.setTitle(title.replaceAll("'", "\""));
			sysLog.setContent(content.replaceAll("'", "\""));
			sysLog.setCreatedBy(createdBy.getUserCode());
			sysLog.setCreatedByName(createdBy.getRealName());
			sysLog.setCreatedTime(current);
			sysLog.setLastUpdatedBy(createdBy.getUserCode());
			sysLog.setLastUpdatedByName(createdBy.getRealName());
			sysLog.setLastUpdatedTime(current);
			sysLog.setLogLevel(logLevel);
			sysLog.setLogType(logType);
			this.systemLogDAO.save(sysLog);
		} catch (SystemCodeNotFoundException e) {
			e.printStackTrace();
			String message = this.messageSource.getMessage(
					"warn.service.syslog.creating.notype",
					new String[] { "NORMAL" },
					"Can not find the code of [NORMAL] log type.",
					Locale.getDefault());
			log.warn(message);
		} catch (SystemCodeDuplicateException e) {
			e.printStackTrace();
			String message = this.messageSource.getMessage(
					"warn.service.syslog.creating.dupltype",
					new String[] { "NORMAL" },
					"Duplicate results were found as log type [NORMAL].",
					Locale.getDefault());
			log.warn(message);
		}
	}

	/**
	 * @see org.xlab.baseframework.service.api.ISystemLogService#createSystemLog(org.xlab.baseframework.exception.SystemRuntimeException,
	 *      org.xlab.baseframework.domain.ISystemUserDomain)
	 */
	public void createSystemLog(SystemRuntimeException ex,
			EnumLogLevel logLevel, ISystemUserDomain createdBy) {
		SystemCode logType = null;
		try {
			logType = this.systemCodeService.findByCode(
					PlatformDeclare.CODE_OF_LOGTYPE_EXCEPTION, true);
			Date current = new Date();
			SystemLog sysLog = new SystemLog();
			sysLog.setTitle(ex.getMessage().replaceAll("'", "\""));
			sysLog.setContent(ex.getCause().toString().replaceAll("'", "\""));
			sysLog.setCreatedBy(createdBy.getUserCode());
			sysLog.setCreatedByName(createdBy.getRealName());
			sysLog.setCreatedTime(current);
			sysLog.setLastUpdatedBy(createdBy.getUserCode());
			sysLog.setLastUpdatedByName(createdBy.getRealName());
			sysLog.setLastUpdatedTime(current);
			sysLog.setLogLevel(logLevel);
			sysLog.setLogType(logType);
			this.systemLogDAO.save(sysLog);
		} catch (SystemCodeNotFoundException e) {
			e.printStackTrace();
			String message = this.messageSource.getMessage(
					"warn.service.syslog.creating.notype",
					new String[] { "EXCEPTION" },
					"Can not find the code of [EXCEPTION] log type.",
					Locale.getDefault());
			log.warn(message);
			log.warn("Skip logging...");
		} catch (SystemCodeDuplicateException e) {
			e.printStackTrace();
			String message = this.messageSource.getMessage(
					"warn.service.syslog.creating.dupltype",
					new String[] { "EXCEPTION" },
					"Duplicate results were found as log type [EXCEPTION].",
					Locale.getDefault());
			log.warn(message);
		}
	}

	/**
	 * @see org.xlab.baseframework.service.api.ISystemLogService#deleteSystemLog(org.xlab.baseframework.domain.SystemLog)
	 */
	public void deleteSystemLog(SystemLog sysLog) {
		this.systemLogDAO.remove(sysLog);
	}

	/**
	 * @see org.xlab.baseframework.service.api.ISystemLogService#findAllByQueryObject(org.xlab.baseframework.domain.query.SystemLogQueryObject)
	 */
	public List<SystemLog> findAllByQueryObject(SystemLogQueryObject queryObject)
			throws SystemLogNotFoundException {

		try {
			return this.systemLogDAO.findAllByQueryObject(queryObject);
		} catch (ObjectNotFoundException e) {
			throw new SystemLogNotFoundException(e);
		}
	}

	/**
	 * @return the messageSource
	 */
	public MessageSource getMessageSource() {
		return messageSource;
	}

	/**
	 * @return the systemCodeService
	 */
	public ISystemCodeService getSystemCodeService() {
		return systemCodeService;
	}

	/**
	 * @return the systemLogDAO
	 */
	public ISystemLogDAO getSystemLogDAO() {
		return systemLogDAO;
	}

	/**
	 * @see org.xlab.baseframework.service.api.IBaseService#parseFromVO(org.xlab.baseframework.domain.view.IViewDomainObject)
	 */
	public SystemLog parseFromVO(SystemLogVO viewObject) {
		SystemLog pojo = new SystemLog();
		BeanUtils.copyProperties(viewObject, pojo);
		return pojo;
	}

	/**
	 * @param messageSource
	 *            the messageSource to set
	 */
	public void setMessageSource(MessageSource messageSource) {
		this.messageSource = messageSource;
	}

	/**
	 * @param systemCodeService
	 *            the systemCodeService to set
	 */
	public void setSystemCodeService(ISystemCodeService systemCodeService) {
		this.systemCodeService = systemCodeService;
	}

	/**
	 * @param systemLogDAO
	 *            the systemLogDAO to set
	 */
	public void setSystemLogDAO(ISystemLogDAO systemLogDAO) {
		this.systemLogDAO = systemLogDAO;
	}

}
